package r25.character;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;

import r25.engine.GameInstance;
import r25.engine.IGameInstance.CHARACTER_ACTION;
import r25.engine.IGameService.CHARACTER_ROLE;
import r25.room.IRoom;
import r25.tools.LoggerHelper;
import r25.tools.ParameterHelper2;

public class GenericCharacter extends AbstractInRoomObject implements
		ICharacter {
	private static final Logger logger = LoggerHelper.getLogger();

	private final Map<String, Object> parameters = new HashMap<String, Object>();
	private final ReminderToken reminderToken;
	private boolean isAlive = true;
	private CHARACTER_ROLE role;
	private int player;
	protected GameInstance gameInstance;

	public GenericCharacter() {
		reminderToken = new ReminderToken(this);
	}

	@Override
	public void parameter(Map<String, Object> p) throws Exception {
		parameters.putAll(p);
		setName((String) parameters.get("name"));
	}

	@Override
	public String toString(boolean withRoomIn) {
		return "[ " + ((!isAlive()) ? "DEAD " : "") + getName() + ":" + getId()
				+ ":" + getRole() + " P" + getPlayer()
				+ ((withRoomIn) ? " @ " + getRoomIn() : "") + " ]";
	}

	@Override
	public String toString() {
		return toString(false);
	}

	@Override
	public boolean isAlive() {
		return isAlive;
	}

	@Override
	public void setAlive(boolean isAlive) {
		this.isAlive = isAlive;
	}

	@Override
	public void setName(String name) {
		super.setName(name);
		getReminderToken().setName(name);
	}

	@Override
	public boolean isReminderTokenUsable() {
		return isAlive() && (reminderToken.getRoomIn() == null);
	}

	@Override
	public ReminderToken getReminderToken() {
		return reminderToken;
	}

	@Override
	public CHARACTER_ROLE getRole() {
		return role;
	}

	@Override
	public void setRole(CHARACTER_ROLE role) {
		this.role = role;
	}

	@Override
	public ICharacter newInstance() {
		try {
			return ParameterHelper2.newInstance(parameters);
		} catch (Exception e) {
			logger.error("", e);
		}
		return null;
	}

	@Override
	public void setPlayer(int player) {
		this.player = player;
	}

	@Override
	public int getPlayer() {
		return player;
	}

	@Override
	public int countCharacterActions() {
		if (isAlive() && (getRoomIn() != null)) {
			return getRoomIn().countCharacterActions();
		} else {
			return 0;
		}
	}

	@Override
	public List<CHARACTER_ACTION> availableCharacterActions() {
		if (isAlive() && (getRoomIn() != null)) {
			return getRoomIn().availableCharacterActions();
		} else {
			return new ArrayList<CHARACTER_ACTION>();
		}
	}

	@Override
	public void setGameInstance(GameInstance gameInstance) {
		this.gameInstance = gameInstance;
	}

	@Override
	public CHARACTER_ACTION moveInRoom(IRoom room) throws Exception {
		super.moveInRoom(room);
		return room.onEnter(gameInstance, this);
	}
}
